require('../db/mongodb').load();
const mongoose = require('mongoose');
const express = require('express');
const multiparty = require('connect-multiparty');
const multipartMiddleware = multiparty();
const app = express();
const fs = require('fs');
const path = require('path');
const bodyParser = require('body-parser');
const config=require('../config');
// const OSSHelper = require('../util/OSSHelper')
// OSSHelper.init(config.oss)
// const HotEventStatics = require('./HotEventStatics')

if(!config.debug){
    const https = require('https');
    const privateKey = fs.readFileSync('./cert/ppt/2880273_ppt.073c.com.key');
    const certificate = fs.readFileSync('./cert/ppt/2880273_ppt.073c.com.pem');
    const credentials = {key: privateKey, cert: certificate};
    const httpsServer = https.createServer(credentials, app);
    httpsServer.listen(config.web.sslPort, function () {
        console.log('HTTPS Server is running on: https://localhost:%s', config.web.sslPort);
    });
}else{
    const http = require('http');
    const httpServer = http.createServer(app);
    httpServer.listen(config.web.webPort, function () {
        console.log('HTTP Server is running on: http://localhost:%s', config.web.webPort);
    });
}

app.use(express.static(path.join(__dirname, '../public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.all('*', function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By", ' 3.2.1');
    res.header("Content-Type", "application/json;charset=utf-8");
    res.data = function (data) {
        this.json({code: 200, data: data});
    };
    next();
});

const queue = require('queue');
Queue=queue({autostart:true});
// Queue.pushTry=function(fun){
//     Queue.push(function(){
//         try{
//             this.fun();
//         }catch(e){
//             console.error(e);
//             const mongoose = require('mongoose');
//             const ErrorModel=mongoose.models['Error'];
//             ErrorModel.create({
//                 stack:JSON.stringify(e.stack)
//             });
//         }
//     }.bind({fun:fun}))
// };


app.get('/game/gameUser',async function(req,res,next){
    Queue.push(async function(){
        try{
            console.log('options =', this.req.query);
            let time = Date.now();
            const GameUserModel=mongoose.models['GameUser'];
            let user=await GameUserModel.findOne({_id:this.req.query._id,token:this.req.query.token});
            if(!user){
                throw new Error(`用户登陆验证失败:${JSON.stringify(req.query)}`);
            }
            this.req.query.self=user;
            let routers=this.req.query.router.split('.');
            let returnData=undefined;
            switch(routers.length){
                case 1:{
                    returnData=await user[routers[0]](this.req.query);
                    break;
                }
                case 2:{
                    returnData=await user[routers[0]][routers[1]](this.req.query);
                    break;
                }
                case 3:{
                    returnData=await user[routers[0]][routers[1]][routers[2]](this.req.query);
                    break;
                }
                case 4:{
                    returnData=await user[routers[0]][routers[1]][routers[2]][routers[3]](this.req.query);
                    break;
                }
            }
            await user.save();
            console.log('gameUser router ==', this.req.query.router, Date.now() - time);
            this.res.data(returnData);
        }catch(e){
            console.log(e);
            this.next(e.message);
        }
    }.bind({req:req,res:res,next:next}));
});

const GPS = require('../util/gps');
const WXBizDataCrypt = require('../util/WXBizDataCrypt');
const HttpHelper = require('../util/httpHelper');
const Common = require('../util/common');
const GameUserModel=mongoose.models['GameUser'];

// app.post('/game/gameUser/qqplayLogin',async function(req,res,next){
//     let msg = req.body;
//     console.log('qqplayLogin:',req.body);
//     try {
//         let imgFile = './'+msg.openid+'.png'
//         let base64Data = msg.imgData.replace(/^data:image\/\w+;base64,/, "");
//         let dataBuffer = new Buffer(base64Data, 'base64');
//         fs.writeFileSync(imgFile,dataBuffer,{encoding:'buffer'})
//         let headImgUrl = await OSSHelper.upload(imgFile,msg.openid+'.png')
//         fs.unlinkSync(imgFile);
//
//         console.log('headImgUrl:',headImgUrl)
//
//         let re = /[^\u4e00-\u9fa5a-zA-Z0-9]/g;
//         let obj = {
//             openid: msg.openid,
//             token: msg.openKey,
//             nickname: msg.nickName.replace(re, ""),
//             sex: msg.sex,
//             headImgUrl: headImgUrl,
//             latitude: '999',
//             longitude: '999',
//             address: '',
//             parentId:req.query.parentId,
//             platform:2
//         };
//         let gameUser=await GameUserModel.weChatLogin(obj);
//         res.data(await gameUser.checkLogin());
//         await gameUser.save();
//     } catch (e) {
//         console.log(e);
//         next('登录信息错误！');
//     }
// });

// app.get('/game/gameUser/baiduLogin',async function(req,res,next){
//     let msg = req.query;
//     console.log('baiduLogin:',req.query);
//     //换取openid和sessionkey
//     let sessionKeyResultStr = await HttpHelper.getLocal(`https://openapi.baidu.com/nalogin/getSessionKeyByCode?client_id=${config.baidu.appid}&sk=${config.baidu.appsecret}&code=${msg.code}`);
//     let sessionKeyResult = JSON.parse(sessionKeyResultStr);
//     if (sessionKeyResult.hasOwnProperty('session_key')) {
//         try {
//             // let pc = new WXBizDataCrypt(config.weChat.appid, sessionKeyResult.session_key);
//             // let gameUserData = pc.decryptData(msg.encryptedData, msg.iv);
//             //根据gps换取地理详细位置
//             // let address = await GPS.getAddress(msg.latitude, msg.longitude);
//
//             let re = /[^\u4e00-\u9fa5a-zA-Z0-9]/g;
//             let obj = {
//                 openid: sessionKeyResult.openid,
//                 token: sessionKeyResult.session_key,
//                 nickname: msg.nickName.replace(re, ""),
//                 sex: msg.gender,
//                 headImgUrl: msg.avatarUrl,
//                 latitude: msg.latitude,
//                 longitude: msg.longitude,
//                 address: '',
//                 parentId:req.query.parentId,
//                 platform:1
//             };
//             let gameUser=await GameUserModel.weChatLogin(obj);
//             res.data(await gameUser.checkLogin());
//             await gameUser.save();
//         } catch (e) {
//             console.log(e);
//             next('登录信息错误！');
//         }
//     } else {
//         next('微信未授权！登录失败！');
//     }
// });

app.get('/game/gameUser/weChatLogin',async function(req,res,next){
    Queue.push(async function() {
        let time = Date.now();
        let msg = this.req.query;
        // console.log('weChatLogin:', this.req.query);
        //换取openid和sessionkey
        let loginType = msg.loginType || 1;
        if(loginType == 3) return res.data({v: true});
        let typeObj = config.platform.find(item => item.loginType == loginType);
        let sessionKeyResult = await Common.getSessionKey(typeObj.appid, typeObj.appsecret, loginType, msg.code, msg.anonymousCode);
        if (sessionKeyResult.hasOwnProperty('session_key')) {
            try {
                let pc = new WXBizDataCrypt(typeObj.appid, sessionKeyResult.session_key);
                let gameUserData = pc.decryptData(msg.encryptedData, msg.iv);
                // console.log('gameUserData ==', gameUserData);
                //根据gps换取地理详细位置
                // let address = await GPS.getAddress(msg.latitude, msg.longitude);
                // let openGId = '';
                // if(!!data.shareIV && !!data.shareEncryptedData){
                //     openGId = pc.decryptData(data.shareEncryptedData,data.shareIV);
                // }

                let re = /[^\u4e00-\u9fa5a-zA-Z0-9]/g;
                let obj = {
                    openid: gameUserData.openId,
                    anonymous_openid: sessionKeyResult.anonymous_openid,
                    token: sessionKeyResult.session_key,
                    nickname: gameUserData.nickName.replace(re, ""),
                    sex: gameUserData.gender,
                    headImgUrl: gameUserData.avatarUrl,
                    latitude: msg.latitude,
                    longitude: msg.longitude,
                    address: '',
                    referrerInfoAppId: this.req.query.channel,
                    parentId: this.req.query.parentId,
                    platform: 0
                };
                let gameUser = await GameUserModel.weChatLogin(obj);
                this.res.data(await gameUser.checkLogin({self:gameUser, version: msg.version}));
                await gameUser.save();
                console.log('weChatLogin router ==', this.req.query.router, Date.now() - time);
            } catch (e) {
                console.log('登陆信息错误:', e);
                this.next('登录信息错误！');
            }
        } else {
            this.next('微信未授权！登录失败！');
        }
    }.bind({req:req,res:res,next:next,config:config}));
});

app.get('/game/gameUser/codeLogin',async function(req,res,next){
    let msg = req.query;
    // console.log('msg =>', req.query);
    //换取openid和sessionkey
    let loginType = msg.loginType || 1;
    if(loginType == 3) return res.data({v: true});
    let obj = config.platform.find(item => item.loginType == loginType);
    let sessionKeyResult = await Common.getSessionKey(obj.appid, obj.appsecret, loginType, msg.code, msg.anonymousCode);
    if (sessionKeyResult.hasOwnProperty('session_key')) {
        try {
            let obj = {
                openid: sessionKeyResult.openid,
                anonymous_openid: sessionKeyResult.anonymous_openid,
                token: sessionKeyResult.session_key,
                referrerInfoAppId: req.query.referrerInfoAppId,
                parentId: req.query.parentId,
                loginType: loginType,
            };
            let gameUser = await GameUserModel.weChatLogin(obj);
            res.data(await gameUser.checkLogin(msg));
        } catch (e) {
            console.log('err========>', e);
            next('登录信息错误！');
        }
    } else {
        next('微信未授权！登录失败！');
    }
});

app.get('/game/gameUser/toutiaoLogin',async function(req,res,next){
    let msg = req.query;
    // console.log('toutiaoLogin:',req.query);
    //换取openid和sessionkey
    let url = `https://developer.toutiao.com/api/apps/jscode2session?appid=${config.toutiao.appid}&secret=${config.toutiao.appsecret}&code=${msg.code}`
    let sessionKeyResultStr = await HttpHelper.getLocal(url);
    // console.log('url:',url,',',sessionKeyResultStr)
    let sessionKeyResult = JSON.parse(sessionKeyResultStr);
    if (sessionKeyResult.hasOwnProperty('session_key')) {
        try {
            let pc = new WXBizDataCrypt(config.toutiao.appid, sessionKeyResult.session_key);
            let gameUserData = pc.decryptData(msg.encryptedData, msg.iv);
            //根据gps换取地理详细位置
            let address = await GPS.getAddress(msg.latitude, msg.longitude);

            let re = /[^\u4e00-\u9fa5a-zA-Z0-9]/g;
            let obj = {
                openid: gameUserData.openId,
                token: sessionKeyResult.session_key,
                nickname: gameUserData.nickName.replace(re, ""),
                sex: gameUserData.gender,
                headImgUrl: gameUserData.avatarUrl,
                latitude: msg.latitude,
                longitude: msg.longitude,
                address: address,
                referrerInfoAppId:req.query.channel,
                parentId:req.query.parentId,
                platform:4
            };
            let gameUser=await GameUserModel.weChatLogin(obj);
            res.data(await gameUser.checkLogin({}));
            await gameUser.save();
        } catch (e) {
            console.log('登陆信息错误:',e);
            next('登录信息错误！');
        }
    } else {
        next('头条未授权！登录失败！');
    }
});

// HotEventStatics.init();
// app.get('/hotevent',function(req,res){
//     HotEventStatics.onStatics(req.query.msg);
//     res.json({code:200})
// });
app.get('/click',async function(req,res){
    let ClickEventModel=mongoose.models['ClickEvent'];
    await ClickEventModel.create({
        timeTick:new Date().getTime(),
        data:{},
        group:req.query.group,
        userId:''
    });
    res.json({code:200});
});

app.use(multiparty({uploadDir:'./public/upload/mp3' }));

app.post('/upload',multipartMiddleware, function (req,res) {
    console.log('上传文件',req.body.fileName);
    let keys=Object.keys(req.files);
    let source = fs.createReadStream(req.files[keys[0]].path);
    let fileName=req.body.fileName;
    let dest = fs.createWriteStream('./public/upload/mp3/'+fileName);
    source.pipe(dest);
    source.on('end', function() { fs.unlinkSync(req.files[keys[0]].path);});   //delete
    source.on('error', function(err) {  });
    res.json({fileName:fileName});
});

app.use(function (err, req, res, next) {
    res.json({code: 500, msg: err});
});
app.use(function (req, res, next) {
    res.json({code: 500, msg: 'no such router'});
});

require('../db/model/gameUser.friendlyLink').run();
require('../db/model/gameUser.rankingList').run();
// require('../db/model/gameUser.rankingList');
// require('../db/default/registerDefaultGameUser')
// require('../db/pptPatch')